package net.avcompris.binding.annotation;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import org.w3c.dom.Node;

/**
 * this annotation is for interfaces and interface methods one wishes to bind
 * to a DOM {@link Node} or a YAML incoming stream. 
 *
 * @author David Andrianavalontsalama
 */
@Documented
@Target({
		TYPE, METHOD
})
@Retention(RUNTIME)
public @interface XPath {

	/**
	 * the effective XPath expression to bind the type (interface) or method to. 
	 */
	String value();

	/**
	 * the XPath function to execute on all nodes found. For instance,
	 * "<tt>name()</tt>" or "<tt>normalize-space()</tt>".
	 */
	String function() default "";

	/**
	 * the XPath function to execute when no node was found for the expression.
	 * For instance "<tt>false</tt>".
	 */
	String failFunction() default "";

	/**
	 * in case of an accessor of type {@link java.util.List},
	 * as opposed to the array case,
	 * you must explicitely declare what is the component type
	 * of the collection. 
	 */
	Class<?> collectionComponentType() default Object.class;

	/**
	 * in case of an accessor of type {@link java.util.Map},
	 * you must explicitely declare what is the map keys' type.
	 */
	Class<?> mapKeysType() default String.class;

	/**
	 * in case of an accessor of type {@link java.util.Map},
	 * you can explicitely declare what is the relative XPath expression
	 * to use to fetch keys. 
	 */
	String mapKeysXPath() default "@id";

	/**
	 * the XPath function to execute on all nodes found for the map keys. 
	 * For instance,
	 * "<tt>name()</tt>" or "<tt>normalize-space()</tt>".
	 */
	String mapKeysFunction() default "";

	/**
	 * in case of an accessor of type {@link java.util.Map},
	 * you must explicitely declare what is the map values' type.
	 */
	Class<?> mapValuesType() default Object.class;

	/**
	 * in case of an accessor of type {@link java.util.Map},
	 * you can explicitely declare what is the relative XPath expression
	 * to use to fetch values. 
	 */
	String mapValuesXPath() default ".";

	/**
	 * the XPath function to execute on all nodes found for the map values. 
	 * For instance,
	 * "<tt>name()</tt>" or "<tt>normalize-space()</tt>".
	 */
	String mapValuesFunction() default "";
}
